package online.heycm.platform.canary.common;

import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * @author heycm
 * @since 2023/12/30 14:00
 */
@Slf4j
public class CanaryRuleCache {

    /**
     * 灰度配置缓存
     */
    private static final List<CanaryRule> RULES = new ArrayList<>();

    public static boolean enable() {
        return !RULES.isEmpty();
    }

    /**
     * 更新灰度配置缓存
     *
     * @param rules 灰度配置
     */
    public static void update(List<CanaryRule> rules) {
        List<CanaryRule> checked = check(rules);
        CanaryRuleCache.RULES.clear();
        if (CollectionUtils.isEmpty(checked)) {
            return;
        }
        CanaryRuleCache.RULES.addAll(checked);
    }

    private static List<CanaryRule> check(List<CanaryRule> rules) {
        List<CanaryRule> effective = new ArrayList<>(rules.size());
        for (CanaryRule rule : rules) {
            if (!checkValue(rule)) {
                log.warn("无效的灰度配置: {}", rule);
            } else {
                if (rule.getEnable()) {
                    effective.add(rule);
                }
            }
        }
        return effective;
    }

    private static boolean checkValue(CanaryRule rule) {
        if (StringUtils.isEmpty(rule.getId())) {
            return false;
        }
        if (StringUtils.isEmpty(rule.getServiceId())) {
            return false;
        }
        if (StringUtils.isEmpty(rule.getPath())) {
            return false;
        }
        if (StringUtils.isEmpty(rule.getCanaryStrategy())) {
            return false;
        }
        if (!CanaryStrategy.contains(rule.getCanaryStrategy())) {
            return false;
        }
        if (StringUtils.isEmpty(rule.getCanaryValue())) {
            return false;
        }
        if (CanaryStrategy.FLOW == CanaryStrategy.ofNullable(rule.getCanaryStrategy())) {
            try {
                boolean checked = CanaryHolder.checkRange(Integer.parseInt(rule.getCanaryValue()));
                if (!checked) {
                    return false;
                }
            } catch (Exception e) {
                return false;
            }
        }
        return true;
    }

    public static List<CanaryRule> rules() {
        return RULES;
    }
}
